import type { Field, XExpression } from '../../../expression';
import type { BaseScalar, Scalar } from '../../../scalar';
import type {
  DefaultRowObject,
  InputObject,
  RowObject,
  RowObjectFrom,
} from '../../../types';
import type { Select } from '../select';
import type { Star } from '../../../object';
import type { SelectColumn } from '../select-column';

export type PickSelectResult<T> = T extends Field<infer V, infer K>
  ? {
      [p in K]: V;
    }
  : T extends SelectColumn<infer V, infer K>
  ? {
      [p in K]: V;
    }
  : {};

export type SelectResult = Field<Scalar, string> | SelectColumn<Scalar, string>;

export type RowTypeByColumns<
  A extends SelectResult,
  B extends SelectResult = Field<never, never>,
  C extends SelectResult = Field<never, never>,
  D extends SelectResult = Field<never, never>,
  E extends SelectResult = Field<never, never>,
  F extends SelectResult = Field<never, never>,
  G extends SelectResult = Field<never, never>,
  H extends SelectResult = Field<never, never>,
  I extends SelectResult = Field<never, never>,
  J extends SelectResult = Field<never, never>,
  K extends SelectResult = Field<never, never>,
  L extends SelectResult = Field<never, never>,
  M extends SelectResult = Field<never, never>,
  N extends SelectResult = Field<never, never>,
  O extends SelectResult = Field<never, never>,
  P extends SelectResult = Field<never, never>,
  Q extends SelectResult = Field<never, never>,
  R extends SelectResult = Field<never, never>,
  S extends SelectResult = Field<never, never>,
  T extends SelectResult = Field<never, never>,
  U extends SelectResult = Field<never, never>,
  V extends SelectResult = Field<never, never>,
  W extends SelectResult = Field<never, never>,
  X extends SelectResult = Field<never, never>,
  Y extends SelectResult = Field<never, never>,
  Z extends SelectResult = Field<never, never>
> = PickSelectResult<A> &
  PickSelectResult<B> &
  PickSelectResult<C> &
  PickSelectResult<D> &
  PickSelectResult<E> &
  PickSelectResult<F> &
  PickSelectResult<G> &
  PickSelectResult<H> &
  PickSelectResult<I> &
  PickSelectResult<J> &
  PickSelectResult<K> &
  PickSelectResult<L> &
  PickSelectResult<M> &
  PickSelectResult<N> &
  PickSelectResult<O> &
  PickSelectResult<P> &
  PickSelectResult<Q> &
  PickSelectResult<R> &
  PickSelectResult<S> &
  PickSelectResult<T> &
  PickSelectResult<U> &
  PickSelectResult<V> &
  PickSelectResult<W> &
  PickSelectResult<X> &
  PickSelectResult<Y> &
  PickSelectResult<Z>;

/**
 * 自动列名前缀
 */
export const COLUMN_NAME_PREEFIX = '#column_';
export type DefaultColumnName = '#column_1';
export const DEFAULT_COLUMN_NAME: DefaultColumnName = '#column_1';
/**
 * SELECT函数签名
 */
export type SelectAction = {
  /**
   * 整表返回
   */
  <T extends RowObject>(a: Star<T>): Select<T>;
  /**
   * 单个值查询
   */
  // <T extends Scalar>(value: CompatibleExpression<T>): Select<{
  //   '#column_1': T;
  // }>;
  <T extends InputObject>(results: T): Select<RowObjectFrom<T>>;
  <T extends BaseScalar>(expr: XExpression<T>): Select<{
    '*no name': T;
  }>;
  <T extends RowObject>(results: InputObject<T>): Select<T>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult,
    U extends SelectResult,
    V extends SelectResult,
    W extends SelectResult,
    X extends SelectResult,
    Y extends SelectResult,
    Z extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T,
    u: U,
    v: V,
    w: W,
    x: X,
    y: Y,
    z: Z
  ): Select<
    RowTypeByColumns<
      A,
      B,
      C,
      D,
      E,
      F,
      G,
      H,
      I,
      J,
      K,
      L,
      M,
      N,
      O,
      P,
      Q,
      R,
      S,
      T,
      U,
      V,
      W,
      X,
      Y,
      Z
    >
  >;
  <A extends SelectResult>(a: A): Select<RowTypeByColumns<A>>;
  <A extends SelectResult, B extends SelectResult>(a: A, b: B): Select<
    RowTypeByColumns<A, B>
  >;
  <A extends SelectResult, B extends SelectResult, C extends SelectResult>(
    a: A,
    b: B,
    c: C
  ): Select<RowTypeByColumns<A, B, C>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D
  ): Select<RowTypeByColumns<A, B, C, D>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E
  ): Select<RowTypeByColumns<A, B, C, D, E>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F
  ): Select<RowTypeByColumns<A, B, C, D, E, F>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I, J>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M, N>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P
  ): Select<RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>>;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q
  ): Select<
    RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q>
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R
  ): Select<
    RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R>
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S
  ): Select<
    RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S>
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T
  ): Select<
    RowTypeByColumns<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T>
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult,
    U extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T,
    u: U
  ): Select<
    RowTypeByColumns<
      A,
      B,
      C,
      D,
      E,
      F,
      G,
      H,
      I,
      J,
      K,
      L,
      M,
      N,
      O,
      P,
      Q,
      R,
      S,
      T,
      U
    >
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult,
    U extends SelectResult,
    V extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T,
    u: U,
    v: V
  ): Select<
    RowTypeByColumns<
      A,
      B,
      C,
      D,
      E,
      F,
      G,
      H,
      I,
      J,
      K,
      L,
      M,
      N,
      O,
      P,
      Q,
      R,
      S,
      T,
      U,
      V
    >
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult,
    U extends SelectResult,
    V extends SelectResult,
    W extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T,
    u: U,
    v: V,
    w: W
  ): Select<
    RowTypeByColumns<
      A,
      B,
      C,
      D,
      E,
      F,
      G,
      H,
      I,
      J,
      K,
      L,
      M,
      N,
      O,
      P,
      Q,
      R,
      S,
      T,
      U,
      V,
      W
    >
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult,
    U extends SelectResult,
    V extends SelectResult,
    W extends SelectResult,
    X extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T,
    u: U,
    v: V,
    w: W,
    x: X
  ): Select<
    RowTypeByColumns<
      A,
      B,
      C,
      D,
      E,
      F,
      G,
      H,
      I,
      J,
      K,
      L,
      M,
      N,
      O,
      P,
      Q,
      R,
      S,
      T,
      U,
      V,
      W,
      X
    >
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult,
    U extends SelectResult,
    V extends SelectResult,
    W extends SelectResult,
    X extends SelectResult,
    Y extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T,
    u: U,
    v: V,
    w: W,
    x: X,
    y: Y
  ): Select<
    RowTypeByColumns<
      A,
      B,
      C,
      D,
      E,
      F,
      G,
      H,
      I,
      J,
      K,
      L,
      M,
      N,
      O,
      P,
      Q,
      R,
      S,
      T,
      U,
      V,
      W,
      X,
      Y
    >
  >;
  <
    A extends SelectResult,
    B extends SelectResult,
    C extends SelectResult,
    D extends SelectResult,
    E extends SelectResult,
    F extends SelectResult,
    G extends SelectResult,
    H extends SelectResult,
    I extends SelectResult,
    J extends SelectResult,
    K extends SelectResult,
    L extends SelectResult,
    M extends SelectResult,
    N extends SelectResult,
    O extends SelectResult,
    P extends SelectResult,
    Q extends SelectResult,
    R extends SelectResult,
    S extends SelectResult,
    T extends SelectResult,
    U extends SelectResult,
    V extends SelectResult,
    W extends SelectResult,
    X extends SelectResult,
    Y extends SelectResult,
    Z extends SelectResult
  >(
    a: A,
    b: B,
    c: C,
    d: D,
    e: E,
    f: F,
    g: G,
    h: H,
    i: I,
    j: J,
    k: K,
    l: L,
    m: M,
    n: N,
    o: O,
    p: P,
    q: Q,
    r: R,
    s: S,
    t: T,
    u: U,
    v: V,
    w: W,
    x: X,
    y: Y,
    z: Z
  ): Select<
    RowTypeByColumns<
      A,
      B,
      C,
      D,
      E,
      F,
      G,
      H,
      I,
      J,
      K,
      L,
      M,
      N,
      O,
      P,
      Q,
      R,
      S,
      T,
      U,
      V,
      W,
      X,
      Y,
      Z
    >
  >;
  <T extends RowObject>(fields: SelectColumn): Select<T>;
  <T extends Scalar>(
    ...results: (Star | XExpression<T> | SelectColumn)[]
  ): Select<DefaultRowObject>;
};
